home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
PROBLEMS
/
C
/
UFN_ROFN
< prev
Wrap
Text File
|
1991-04-28
|
11KB
|
343 lines
/*
Recetly I noticed a lot of talk about a routine to convert UNIX
filenames to RISC OS filenames, but as of yet no one has come up
with the goods !
So to start the ball rolling I'll post this rather awful routine
which does the job. It's written in C and is probably too
unintelligible to be ported to any other language. I use it in my
programs - which I've just posted, and it hasn't failed me yet.
When compiling, try :
cc c.ufn_rofn -DTEST
if you want to test it out.
That's all folks !
Steven van Aardt
(If we've any Dutch Users I'd like your opinion of the origins
of my surname, it apparently has an Afrikanns background.)
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
| | | | | | | | | | | | C U T B E L O W | | | | | | | | | | | | | | | | |
'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'-'
*/
/*----------------------------------------------------*
* Module : c.ufn_rofn
* Purpose: Convert UNIX filenames to RiscOS filename
* Author : Steven van Aardt
*----------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FALSE 0
#define TRUE (!FALSE)
#define MAX_FILENAME 10
/*---------------------------- Reverse ------------------------*
* Purpose: Reverse the character sequence within a string
* Arguments: Pointer to string
* Returns: Pointer to the same string given as an argument.
*-------------------------------------------------------------*/
static
char *reverse(char *string)
{
int hd=0,tl=strlen(string);
char tmp_c;
/* reverse the name */
while (--tl>hd) { /* work way back from end of string */
tmp_c=string[hd];
string[hd++]=string[tl];
string[tl]=tmp_c;
}
return string;
}
/*---------------------------- isvowel --------------------------------*
* Purpose: Determines whether a character is an alphabetical vowel
* Arguments: character (integer form)
* Returns: TRUE if vowel, otherwise FALSE.
*---------------------------------------------------------------------*/
static
int isvowel(int c)
{
int vowel=FALSE;
switch (c) {
case 'a': case 'A': /* if c matches with */
case 'e': case 'E': /* any of these function */
case 'i': case 'I': /* will return TRUE */
case 'o': case 'O':
case 'u': case 'U': vowel=TRUE;
}
return vowel;
}
/*-------------------- squeeze ------------------------*
* Purpose: remove any space characters from a string
* Arguments: pointer to string
* Returns: pointer to a new string.
*-------------------------------------------------------*/
static
char *squeeze(char *ptr)
{
int i=0,j=0;
char *nn=NULL;
/* squeeze in-place */
for (i=j=0; ptr[i]!='\0';i++) if (ptr[i]!=' ') ptr[j++]=ptr[i];
/* and copy into a new string */
nn=calloc(j+2,sizeof(char)); /* allocate enough memory for new string */
strncpy(nn,ptr,j);
return nn;
}
/*---------------------------- rm_vowels -----------------------------*
* Purpose: removes some vowels from a string thus shortening it
* Arguments: pointer to string
* Returns: pointer to a new string.
*--------------------------------------------------------------------*/
static
char *rm_vowels(char *word,int maxlen)
{
char *new_word=NULL;
if (word) {
int len=strlen(word);
char *cpy=calloc(len+1,sizeof(char));
strcpy(cpy,word);
if (len>maxlen) {
/* remove every 2nd vowel */
int i;
len--; /* leave last letter */
for (i=1; i<len; i+=2) {
while ((i<len) && (!isvowel(cpy[i]))) i++; /* skip non-vowels */
if ((i<len) && (isvowel(cpy[i]))) cpy[i]=' '; /* overwrite vowels */
}
}
new_word=squeeze(cpy);
free(cpy);
}
return new_word;
}
/*------------------- shorten ----------------------*
* Purpose: Shortens a string to a specified length
* Arguments: pointer to string
* max length of string to be.
* Returns: Pointer to new string
*----------------------------------------------------*/
static
char *shorten(char *ptr,int maxlen)
{
char *new_ptr;
int l=strlen(ptr);
if (l>maxlen) {
/* quick shortening by removing a chunk from the middle */
int num=l-maxlen; /* number to remove to get length of 10 */
int i,j=0;
for (i=(l-num)/2; j<num; j++) ptr[i+j]=' ';
}
new_ptr=squeeze(ptr);
return new_ptr;
}
/*--------------------- ufn_rofn ------------------------*
* Purpose: Convert UNIX filename to RISC OS filename
* Arguments: pointer to UNIX filename string
* Returns: pointer to RISC OS filename
*-------------------------------------------------------*/
extern
char *ufn_rofn(char *unix_name)
{
typedef struct l List; /* structure for constituent parts */
struct l { char *ptr; struct l *last,*next; };
int len;
char *uname=calloc(strlen(unix_name)+1,sizeof(char)),*rname=NULL,*ptr=NULL;
List *lptr=NULL,*hdptr=NULL,*tlptr=NULL;
while ((unix_name) && (*unix_name==' ')) unix_name++;
if ((unix_name) && (*unix_name)) {
strcpy(uname,unix_name);
/* look for root directory '/' at beginning of unix filename */
if (uname[0]=='/') {
char *tmp=calloc(2,sizeof(char));
strcpy(tmp,"$");
lptr=(List *) malloc(sizeof(List));
tlptr=lptr; /* pointer to beginning of list */
lptr->ptr=tmp;
lptr->next=NULL;
lptr->last=hdptr;
hdptr=lptr; /* pointer to end of list */
}
/*
* Break down the name into its directory components - destroys uname
*/
ptr=strtok(uname,"/"); /* ignores / if at beginning of list */
while (ptr) {
char *tmp=calloc(strlen(ptr)+1,sizeof(char));
strcpy(tmp,ptr);
lptr=(List *) malloc(sizeof(List));
if (!tlptr) tlptr=lptr; /* make pointer to beginning of list */
if (hdptr) hdptr->next=lptr; /* link previous element onto this */
lptr->ptr=tmp;
lptr->next=NULL;
lptr->last=hdptr; /* reverse chained list */
hdptr=lptr;
ptr=strtok(NULL,"/"); /* find next '/' */
}
/*
* Now go through each component looking for a '.' within each.
*/
lptr=tlptr; /* beginning of list */
while (lptr) {
char *dp=NULL; /* dot position */
dp=strchr(lptr->ptr,'.');
if (dp) {
int len=strlen(lptr->ptr);
/*
* special cases
*/
/* if only 1 dot then refers to the UNIX csd */
if (len==1) {
char *tmp=calloc(2,sizeof(char));
strcpy(tmp,"@");
lptr->ptr=tmp;
} else {
if (len==2) {
char *tmp=calloc(2,sizeof(char));
strcpy(tmp,"^");
lptr->ptr=tmp;
} else {
/*
* General case requires reversing of parts around '.'
*/
List *dlptr=NULL, *dhdptr=NULL, *dtlptr=NULL,*tmp_next=lptr->next;
char *dptr=NULL,*cpy=calloc(len+1,sizeof(char));
strcpy(cpy,lptr->ptr);
reverse(cpy); /* reverse complete text */
dptr=strtok(cpy,".");
while (dptr) {
char *tmp=calloc(strlen(dptr)+1,sizeof(char));
strcpy(tmp,dptr); /* make a copy of part */
dlptr=(List *) malloc(sizeof(List));
if (!dtlptr) dtlptr=dlptr; /* remember beginning of this list */
if (dhdptr) dhdptr->next=dlptr; /* link previous one onto this */
dlptr->ptr=reverse(tmp); /* and reverse it's text back again */
dlptr->next=NULL;
dlptr->last=dhdptr; /* reverse chaining */
dhdptr=dlptr;
dptr=strtok(NULL,".");
} /* endwhile */
if (lptr->last) {
free(lptr->ptr); /* free text worked on by above */
lptr=lptr->last; /* move back */
free(lptr->next); /* free text's list element */
lptr->next=dtlptr; /* link */
dtlptr->last=lptr;
dlptr->next=tmp_next;
if (tmp_next) {
tmp_next->last=dlptr;
lptr=tmp_next->last;
} else lptr=dlptr;
} else { /* case when this is the head of the list */
free(lptr->ptr);
free(lptr);
lptr=dtlptr;
tlptr=lptr;
lptr->last=NULL;
dlptr->next=tmp_next;
if (tmp_next) {
tmp_next->last=dlptr;
lptr=tmp_next->last;
} else lptr=dlptr;
} /* endif */
} /* endif */
} /* endif */
} /* endif */
lptr=lptr->next; /* move onto next directory component in list */
} /* endwhile */
/*
* Check the lengths of each component and adjust to that for RISC OS
*/
lptr=tlptr;
len=0;
while (lptr) {
char *new_ptr=NULL;
if (lptr->next) len+=1; /* for the RISC OS directory separator */
new_ptr=rm_vowels(lptr->ptr,MAX_FILENAME);
free(lptr->ptr);
lptr->ptr=new_ptr;
new_ptr=shorten(lptr->ptr,MAX_FILENAME);
free(lptr->ptr);
lptr->ptr=new_ptr;
len+=strlen(lptr->ptr);
lptr=lptr->next;
}
/*
* Copy linked list into result string
*/
rname=calloc(len+1,sizeof(char)); /* make suitable string space */
lptr=tlptr;
len=0;
while (lptr) {
strcat((rname+len),lptr->ptr);
free(lptr->ptr);
len=strlen(rname);
lptr=lptr->next;
if (lptr) strcat(rname,"."); /* append RISC OS directory separator */
}
/*
* Tidy up, by freeing memory used by list
*/
lptr=tlptr;
while (lptr) {
List *tmp;
tmp=lptr;
lptr=lptr->next;
free(tmp);
}
} /* endif */
free(uname);
return rname;
}
#ifdef TEST
int main(void) {
char unix_filename[256],*riscos_filename;
while (!feof(stdin)) {
printf("Enter Unix filename : ");
scanf("%s",&unix_filename);
if (!feof(stdin)) {
riscos_filename=ufn_rofn(unix_filename);
printf("Risc OS filename : %s\n",riscos_filename);
free(riscos_filename);
}
}
return 0;
}
#endif
/*
+--------------------------------+-----------------------------------------+
| ()()TEVEN () | |
| () ()() | |
| ()() () ()AN () () | |
| () ()() ()()()() +-----------------------------------------+
| ()() () () ()ARDT |JANET E-mail : vanaards@uk.ac.man.cs.p4 |
+--------------------------------+-----------------------------------------+
*/